multiselection: Fix the select_range implementation
authorMatthias Clasen <mclasen@redhat.com>
Fri, 5 Jun 2020 17:49:32 +0000 (13:49 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Fri, 5 Jun 2020 18:57:59 +0000 (14:57 -0400)
When exclusive is TRUE, we would not always emit a
::selection-changed signal that covers all the items
that were unselected.

This commit includes a test.

gtk/gtkmultiselection.c
testsuite/gtk/multiselection.c

index 00d02998d5692b8d67d7de411333cc2b624d15e0..31572072a74bfa9167733db154c315820d1bb048 100644 (file)
@@ -109,11 +109,22 @@ gtk_multi_selection_select_range (GtkSelectionModel *model,
                                   gboolean           exclusive)
 {
   GtkMultiSelection *self = GTK_MULTI_SELECTION (model);
+  guint min = G_MAXUINT;
+  guint max = 0;
 
   if (exclusive)
-    gtk_set_remove_all (self->selected);
+    {
+      min = gtk_set_get_min (self->selected);
+      max = gtk_set_get_max (self->selected);
+      gtk_set_remove_all (self->selected);
+    }
+
   gtk_set_add_range (self->selected, position, n_items);
-  gtk_selection_model_selection_changed (model, position, n_items);
+
+  min = MIN (position, min);
+  max = MAX (max, position + n_items - 1);
+
+  gtk_selection_model_selection_changed (model, min, max - min + 1);
 
   return TRUE;
 }
index b00c68c7c8bc6a009dcef952f02e871aa8297eb3..4e8622e0ebb0fc4e5f61580efc974b5072c654f8 100644 (file)
@@ -372,6 +372,38 @@ test_selection (void)
   g_object_unref (selection);
 }
 
+static void
+test_select_range (void)
+{
+  GtkSelectionModel *selection;
+  GListStore *store;
+  gboolean ret;
+
+  store = new_store (1, 5, 1);
+  selection = new_model (store);
+  assert_selection (selection, "");
+  assert_selection_changes (selection, "");
+
+  ret = gtk_selection_model_select_range (selection, 2, 2, FALSE);
+  g_assert_true (ret);
+  assert_selection (selection, "3 4");
+  assert_selection_changes (selection, "2:2");
+
+  ret = gtk_selection_model_select_range (selection, 3, 2, FALSE);
+  g_assert_true (ret);
+  assert_selection (selection, "3 4 5");
+  assert_selection_changes (selection, "3:2");
+
+  ret = gtk_selection_model_select_range (selection, 0, 1, TRUE);
+  g_assert_true (ret);
+  assert_selection (selection, "1");
+  assert_selection_changes (selection, "0:5");
+
+  g_object_unref (store);
+  g_object_unref (selection);
+}
+
+
 int
 main (int argc, char *argv[])
 {
@@ -388,6 +420,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/multiselection/changes", test_changes);
 #endif
   g_test_add_func ("/multiselection/selection", test_selection);
+  g_test_add_func ("/multiselection/select-range", test_select_range);
 
   return g_test_run ();
 }